
#include "../common/dynamic_arr.h"
#include "../common/mem.h"

dynamic_arr* dynamic_arr__allocate()
{
	dynamic_arr* arr;

	arr = mem_alloc_and_zero(1, sizeof(dynamic_arr));
	validate_allocation(arr, "the dynamic array");

	arr->capacity = 1;
	arr->values = mem_alloc(arr->capacity, sizeof(dynamic_arr_type));
	validate_allocation(arr->values, "the values buffer in the dynamic array");

	return arr;
}

void dynamic_arr__grow(dynamic_arr* arr)
{
	int previous_capacity;
	dynamic_arr_type* values_ptr;

	previous_capacity = arr->capacity;

	arr->capacity = previous_capacity * 2;
	values_ptr = arr->values;
	arr->values = mem_alloc(arr->capacity, sizeof(dynamic_arr_type));
	validate_allocation(arr->values, "a larger dynamic array");

	memcpy(arr->values, values_ptr, arr->count * sizeof(dynamic_arr_type));

	/*  Free old values array */
	mem_free(values_ptr);
}

void dynamic_arr__add(dynamic_arr* arr, dynamic_arr_type value)
{
	/*  Handle dynamic growth */
	if (arr->count == arr->capacity)
		dynamic_arr__grow(arr);

	/*  Add the value to the array and update the count */
	arr->values[arr->count++] = value;
}

void dynamic_arr__read_from_stream(dynamic_arr* arr, FILE* stream)
{
	dynamic_arr_type value;

	while (!feof(stream))
	{
		if (!fscanf(stream, dynamic_arr_type_scan_format, &value) != 1)
			fatal_error("bad value format in stream");

		dynamic_arr__add(arr, value);
	}
}

void dynamic_arr__read_from_file(dynamic_arr* arr, const char* filename)
{
	FILE* stream;

	stream = fopen(filename, "r");

	if (stream == 0)
		fatal_error("Could not open file for reading.");

	dynamic_arr__read_from_stream(arr, stream);

	fclose(stream);
}

dynamic_arr* dynamic_arr__create_from_file(const char* filename)
{
	dynamic_arr* arr;

	arr = dynamic_arr__allocate();
	dynamic_arr__read_from_file(arr, filename);

	return arr;
}

void dynamic_arr__free(dynamic_arr* arr)
{
	mem_free(arr->values);
	mem_free(arr);
}

